package com.wl156.activities.find;

import java.util.List;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
import com.wl156.R;

public class PlaceMap extends MapActivity implements OnClickListener {

	private static final String TAG = null;

	private static final int UPDATE_LATLNG = 2;

	private static final int TEN_SECONDS = 10000;
	private static final int TEN_METERS = 10;
	private static final int TWO_MINUTES = 1000 * 60 * 2;

	private MapView mMapView;
	String longtitude;
	String latitude;
	String name;
	private Button mRefresh;

	private LocationManager mLocationManager;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.act_place_map);

		mMapView = (MapView) findViewById(R.id.mapview);
		mRefresh = (Button) findViewById(R.id.refresh);
		mRefresh.setOnClickListener(this);

		Bundle extras = getIntent().getExtras();
		if (extras != null) {
			longtitude = extras.getString("longitude");
			latitude = extras.getString("latitude");
			name = extras.getString("name");
			Drawable marker = getResources().getDrawable(R.drawable.map_marker);
			marker.setBounds(0, 0, marker.getIntrinsicWidth(),
					marker.getIntrinsicHeight());
			PlaceOverlay overlay = new PlaceOverlay(marker, name);
			mMapView.getOverlays().clear();
			mMapView.getOverlays().add(overlay);

			GeoPoint pt = overlay.getCenter(); // get the first-ranked point
			mMapView.getController().setCenter(pt);
			// 设置地图的缩放级别。这个值的取值范围是[1,21],
			mMapView.getController().setZoom(15);
		} else {
			try {
				name = "我的位置";
				mLocationManager = (LocationManager) this
						.getSystemService(Context.LOCATION_SERVICE);

				// mConfirm.setText("定位中，请稍候");

				showOverlay();

				// openGPSSettings();
			} catch (Exception e) {
			}
		}

	}
	
	private void showOverlay() {
		Drawable marker = getResources().getDrawable(
				R.drawable.map_marker);
		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight());
		PlaceOverlay overlay = new PlaceOverlay(marker, name);
		mMapView.getOverlays().clear();
		mMapView.getOverlays().add(overlay);

		GeoPoint pt = overlay.getCenter(); // get the first-ranked
											// point
		mMapView.getController().setCenter(pt);
		// 设置地图的缩放级别。这个值的取值范围是[1,21],
		mMapView.getController().setZoom(15);
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	class PlaceOverlay extends ItemizedOverlay<OverlayItem> {
		GeoPoint gp;
		Drawable defaultMarker;
		String name;

		public PlaceOverlay(Drawable defaultMarker, String name) {
			super(defaultMarker);
			this.defaultMarker = defaultMarker;
			this.name = name;

			Log.d(TAG, "latitude: " + latitude + ", longtitude: " + longtitude);
			gp = new GeoPoint((int) (Double.valueOf(latitude) * 1E6),
					(int) (Double.valueOf(longtitude) * 1E6));
			populate();
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {

			try {
				Projection projection = mapView.getProjection();
				OverlayItem overLayItem = getItem(0); // 得到给定索引的item
				String title = overLayItem.getTitle();
				// 把经纬度变换到相对于MapView左上角的屏幕像素坐标
				Point point = projection.toPixels(overLayItem.getPoint(), null);
				// Paint paintCircle = new Paint();
				// paintCircle.setColor(Color.RED);
				// canvas.drawCircle(point.x, point.y, 5, paintCircle); // 画圆
				Paint paintText = new Paint();
				paintText.setColor(Color.RED);
				paintText.setAntiAlias(true);
				paintText.setFakeBoldText(true);
				paintText.setTextSize(20);
				canvas.drawText(title, point.x - paintText.measureText(title)
						/ 2, point.y - defaultMarker.getIntrinsicHeight() - 5,
						paintText); // 绘制文本

				super.draw(canvas, mapView, shadow);
				boundCenterBottom(defaultMarker);
			} catch (Exception e) {
			}
		}

		@Override
		protected OverlayItem createItem(int i) {
			return new OverlayItem(gp, name, "snippet");
		}

		@Override
		public int size() {
			return 1;
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		setup();
	}

	@Override
	protected void onStart() {
		super.onStart();

		// Check if the GPS setting is currently enabled on the device.
		// This verification should be done during onStart() because the system
		// calls this method
		// when the user returns to the activity, which ensures the desired
		// location provider is
		// enabled each time the activity resumes from the stopped state.
		LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		final boolean gpsEnabled = locationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER);

		if (!gpsEnabled) {
			// Build an alert dialog here that requests that the user enable
			// the location services, then when the user clicks the "OK" button,
			// call enableLocationSettings()
			openGPSSettings();
		}
	}

	// Stop receiving location updates whenever the Activity becomes invisible.
	@Override
	protected void onStop() {
		super.onStop();
		mLocationManager.removeUpdates(listener);
	}

	private boolean mUseBoth = true;

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case UPDATE_LATLNG:
				Location l = (Location) msg.obj;
				latitude = String.valueOf(l.getLatitude());
				longtitude = String.valueOf(l.getLongitude());
				Log.d(TAG, "latitude: " + latitude + ", longtitude: " + longtitude);
				showOverlay();
				break;
			}
		}
	};

	// Set up fine and/or coarse location providers depending on whether the
	// fine provider or
	// both providers button is pressed.
	private void setup() {
		Location gpsLocation = null;
		Location networkLocation = null;
		mLocationManager.removeUpdates(listener);
		// Get fine location updates only.
		if (mUseBoth) {
			gpsLocation = requestUpdatesFromProvider(
					LocationManager.GPS_PROVIDER, "不支持gps定位");
			networkLocation = requestUpdatesFromProvider(
					LocationManager.NETWORK_PROVIDER, "不支持网络定位");

			// If both providers return last known locations, compare the two
			// and use the better
			// one to update the UI. If only one provider returns a location,
			// use it.
			if (gpsLocation != null && networkLocation != null) {
				updateUILocation(getBetterLocation(gpsLocation, networkLocation));
			} else if (gpsLocation != null) {
				updateUILocation(gpsLocation);
			} else if (networkLocation != null) {
				updateUILocation(networkLocation);
			}
		}
	}

	/**
	 * Method to register location updates with a desired location provider. If
	 * the requested provider is not available on the device, the app displays a
	 * Toast with a message referenced by a resource id.
	 * 
	 * @param provider
	 *            Name of the requested provider.
	 * @param errorResId
	 *            Resource id for the string message to be displayed if the
	 *            provider does not exist on the device.
	 * @return A previously returned {@link android.location.Location} from the
	 *         requested provider, if exists.
	 */
	private Location requestUpdatesFromProvider(final String provider,
			final String errorResId) {
		Location location = null;
		if (mLocationManager.isProviderEnabled(provider)) {
			mLocationManager.requestLocationUpdates(provider, TEN_SECONDS,
					TEN_METERS, listener);
			location = mLocationManager.getLastKnownLocation(provider);
		} else {
			Toast.makeText(this, errorResId, Toast.LENGTH_LONG).show();
		}
		return location;
	}

	private void updateUILocation(Location location) {
		// We're sending the update to a handler which then updates the UI with
		// the new
		// location.
		Log.d(TAG, "updateUILocation: " + location.toString());
		Message.obtain(mHandler, UPDATE_LATLNG,
				location)
				.sendToTarget();
	}

	private final LocationListener listener = new LocationListener() {

		@Override
		public void onLocationChanged(Location location) {
			// A new location update is received. Do something useful with it.
			// Update the UI with
			// the location update.
			updateUILocation(location);
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

	/**
	 * Determines whether one Location reading is better than the current
	 * Location fix. Code taken from
	 * http://developer.android.com/guide/topics/location
	 * /obtaining-user-location.html
	 * 
	 * @param newLocation
	 *            The new Location that you want to evaluate
	 * @param currentBestLocation
	 *            The current Location fix, to which you want to compare the new
	 *            one
	 * @return The better Location object based on recency and accuracy.
	 */
	protected Location getBetterLocation(Location newLocation,
			Location currentBestLocation) {
		if (currentBestLocation == null) {
			// A new location is always better than no location
			return newLocation;
		}

		// Check whether the new location fix is newer or older
		long timeDelta = newLocation.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
		boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
		boolean isNewer = timeDelta > 0;

		// If it's been more than two minutes since the current location, use
		// the new location
		// because the user has likely moved.
		if (isSignificantlyNewer) {
			return newLocation;
			// If the new location is more than two minutes older, it must be
			// worse
		} else if (isSignificantlyOlder) {
			return currentBestLocation;
		}

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (newLocation.getAccuracy() - currentBestLocation
				.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Check if the old and new location are from the same provider
		boolean isFromSameProvider = isSameProvider(newLocation.getProvider(),
				currentBestLocation.getProvider());

		// Determine location quality using a combination of timeliness and
		// accuracy
		if (isMoreAccurate) {
			return newLocation;
		} else if (isNewer && !isLessAccurate) {
			return newLocation;
		} else if (isNewer && !isSignificantlyLessAccurate
				&& isFromSameProvider) {
			return newLocation;
		}
		return currentBestLocation;
	}

	/** Checks whether two providers are the same */
	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}

	private void openGPSSettings() {
		LocationManager alm = (LocationManager) this
				.getSystemService(Context.LOCATION_SERVICE);
		if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
			Toast.makeText(this, "GPS已经开启", Toast.LENGTH_SHORT).show();
		} else {
			AlertDialog.Builder builer = new Builder(this);
			builer.setMessage("GPS尚未开启，前去开启？");
			builer.setPositiveButton("确定",
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							Intent myIntent = new Intent(
									Settings.ACTION_LOCATION_SOURCE_SETTINGS);
							startActivityForResult(myIntent, 0);
						}
					});
			builer.setNegativeButton("取消",
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
						}
					});
			builer.show();
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.refresh:
			setup();
			mMapView.invalidate();
			break;
		default:
			break;
		}
	}
}
